import axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from "axios";
import store from '@/store';
import { Message } from 'element-ui';
import router from "@/router";
import qs from 'qs';

let isRefreshing = false;
let requests: any[] = [];

const request = axios.create({

});

request.interceptors.request.use((config: AxiosRequestConfig) => {
  const { user } = store.state;
  if (user && user.access_token) {
    (config.headers as AxiosRequestHeaders).Authorization = user.access_token;
  }
  return config;
}, (error) => {
  return Promise.reject(error)
});

request.interceptors.response.use((response: AxiosResponse) => {
  return response;
}, async (error) => {
  // 请求收到响应 但是状态码不是2xx
  if (error.response) {
    const { status } = error.response;

    if (status === 400) {
      Message.error('请求参数错误');
    } else if (status === 401) {
      // Message.error('')
      if (!store.state.user) {
        redirectLogin()
        return Promise.reject(error);
      }
      if (!isRefreshing) {
        isRefreshing = true;
        return refreshTken().then(res => {
          if (!res.data.success) {
            throw new Error('失败');
          }
          store.commit('setUser', res.data.content);
          requests.forEach(cb => cb());
          requests = [];
          // 重新发起失败的请求
          return request(error.config);
        }).catch(() => {
          store.commit('setUser', null);
          redirectLogin();
          return Promise.reject(error);
        }).finally(() => {
          isRefreshing = false;
        })
      }
      // 保证多次（不同类型）接口请求的失败请求能够成功发出
      return new Promise(resolve => {
        requests.push(() => {
          resolve(request(error.config))
        })
      })
    } else if (status === 403) {
      Message.error('没有权限，联系管理员')
    } else if (status === 404) {
      Message.error('请求资源不存在')
    } else if (status >= 500) {
      Message.error('服务端错误，联系管理员')
    }
    // 请求发出去没有收到响应
  } else if (error.request) {
    Message.error('请求超时');
    // 在设置请求事发生错误 触发了错误
  } else {
    Message.error(`请求失败 ${error.message}`);
  }
  // 把请求失败的错误返回给上一个调用者
  return Promise.reject(error);
})

export default request;

function redirectLogin() {
  router.push({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  });
}

async function refreshTken() {
  return await axios.create()({
    method: "POST",
    url: "/front/user/refresh_token",
    data: qs.stringify({
      refreshtoken: store.state.user.refresh_token
    })
  });
}